<template>
	<div class="system-user">
		<div class="pane">
			<div class="dept" :class="[isExpand ? '_expand' : '_collapse']">
				<dict-group />
			</div>
			<div class="user">
				<div class="header">
					<div class="icon" @click="deptExpand">
						<i class="el-icon-arrow-left" v-if="isExpand"></i>
						<i class="el-icon-arrow-right" v-else></i>
					</div>

					<span>{{ title }}</span>
				</div>
				<div class="container">
					<cl-crud :ref="setRefs('crud')" :on-refresh="onRefresh" @load="onLoad">
						<el-row>
							<!-- 刷新按钮 -->
							<cl-refresh-btn />
							<!-- 新增按钮 -->
							<cl-add-btn :disabled="!group" />
							<cl-flex1 />
							<!-- 关键字搜索 -->
							<cl-search-key />
						</el-row>

						<el-row>
							<!-- 数据表格 -->
							<cl-table
								:ref="setRefs('table')"
								v-bind="table"
								:default-sort="{
									prop: 'orderNum',
									order: 'ascending'
								}"
								row-key="id"
								@row-click="onRowClick"
							>
								<template #slot-btn="{ scope }">
									<el-button
										type="text"
										size="mini"
										v-permission="service.dict.info.permission.add"
										@click="append(scope.row)"
										>新增</el-button
									>
								</template>
							</cl-table>
						</el-row>

						<el-row>
							<cl-flex1 />
						</el-row>

						<!-- 新增、编辑 -->
						<cl-upsert :ref="setRefs('upsert')" v-bind="upsert">
							<template #slot-tree-list-select="{ scope }">
								<treeListSelect v-model="scope.parentId" :data="dataTree" />
							</template>
						</cl-upsert>
					</cl-crud>
				</div>
			</div>
		</div>
	</div>
</template>

<script lang="ts" name="dict-list" setup>
import { reactive, computed, ref, provide, watch } from "vue";
import { CrudLoad, Table, Upsert } from "cl-admin-crud-vue3/types";
import { useCool } from "/@/core";
import { deepTree } from "/@/core/utils";
import _ from "lodash";
import DictGroup from "../components/group.vue";
import treeListSelect from "../components/tree.vue";
// 功能
const { refs, setRefs, service, store } = useCool();
console.log(service);

interface Data {
	[key: string]: Array<{ label: string; value: any }>;
}
const data = reactive<Data>({});
// 组
const group = ref();

// 标题
const title = computed(() => {
	return group.value ? `字典列表（${group.value.name}）` : "字典列表";
});

// 标题
const dataTree = computed(() => {
	const data = _.cloneDeep(refs.value.table?.data);

	function deep(d: any, f: boolean) {
		if (d.id && d.id == refs.value.upsert?.getForm("id")) {
			f = true;
		}

		if (f) {
			d.disabled = true;
		}

		if (d.children) {
			d.children.forEach((e: any) => {
				deep(e, f);
			});
		}
	}

	deep({ children: data }, false);
	console.log(data, 123);
	return data;
});
// 是否展开
const isExpand = ref<boolean>(true);
// 浏览器信息
const browser = computed(() => store.getters.browser);

// 监听屏幕大小变化
watch(
	() => browser.value.isMini,
	(val: boolean) => {
		isExpand.value = !val;
	},
	{
		immediate: true
	}
);

// 新增、编辑配置
const upsert = reactive<Upsert>({
	props: {
		labelWidth: "100px"
	},
	items: [
		{
			label: "上级节点",
			prop: "parentId",
			component: {
				name: "slot-tree-list-select"
			}
		},
		{
			label: "名称",
			prop: "name",
			component: { name: "el-input" }
		},
		{
			label: "排序",
			prop: "orderNum",
			value: 1,
			component: { name: "el-input-number", props: { min: 1 } }
		},
		{
			label: "备注",
			prop: "remark",
			component: { name: "el-input", props: { type: "textarea", rows: 4 } }
		}
	],
	onSubmit(isEdit: Boolean, data: any, { done, close, next }: any) {
		next({
			...data,
			typeId: group.value.id
		});
	}
});

// 表格配置
const table = reactive<Table>({
	"context-menu": [
		"refresh",
		(row: any) => {
			return {
				label: "新增",
				hidden: !service.dict.info._permission?.add,
				callback(_: any, done: Function) {
					append(row);
					done();
				}
			};
		},
		"edit",
		"delete",
		"order-asc",
		"order-desc"
	],
	columns: [
		{ label: "名称", prop: "name", align: "left", minWidth: 200 },
		{ label: "排序", prop: "orderNum", sortable: "custom", width: 100 },
		{ label: "备注", prop: "remark", showOverflowTooltip: true, minWidth: 150 },
		{ label: "创建时间", prop: "createTime", sortable: "custom", minWidth: 160 },
		{ label: "更新时间", prop: "updateTime", sortable: "custom", minWidth: 160 },
		{
			type: "op",
			width: 250,
			buttons: ["slot-btn", "edit", "delete"]
		}
	]
});

// crud 加载
function onLoad({ ctx, app }: CrudLoad) {
	// 绑定 service
	ctx.service(service.dict.info).done();
	app.refresh();
}
async function onRefresh(params: any, { render }: any) {
	service.dict.info
		.list({
			typeId: group.value?.id,
			...params,
			page: undefined,
			size: undefined
		})
		.then((res: any) => {
			render(deepTree(res));
		});
}

// 刷新
function refresh(params?: any) {
	refs.value.crud?.refresh(params);
}

// 设置组
function setGroup(data: any) {
	group.value = data;
}
// 是否显示部门
function deptExpand() {
	isExpand.value = !isExpand.value;
}
// 行点击展开
function onRowClick(row: any, column: any) {
	if (column?.property && row.children) {
		refs.value.table?.toggleRowExpansion(row);
	}
}

// 追加子集
function append(row: any) {
	refs.value.crud?.rowAppend({
		parentId: row.id,
		orderNum: 1
	});
}

provide("dict", {
	group,
	refresh,
	setGroup
});
</script>

<style lang="scss" scoped>
.system-user {
	.pane {
		display: flex;
		height: 100%;
		width: 100%;
		position: relative;
	}

	.dept {
		height: 100%;
		width: 300px;
		max-width: calc(100% - 50px);
		background-color: #fff;
		transition: width 0.3s;
		margin-right: 10px;
		flex-shrink: 0;

		&._collapse {
			margin-right: 0;
			width: 0;
		}
	}

	.user {
		width: calc(100% - 310px);
		flex: 1;

		.header {
			display: flex;
			align-items: center;
			justify-content: center;
			height: 40px;
			position: relative;
			background-color: #fff;

			span {
				font-size: 14px;
				white-space: nowrap;
				overflow: hidden;
			}

			.icon {
				position: absolute;
				left: 0;
				top: 0;
				font-size: 18px;
				cursor: pointer;
				background-color: #fff;
				height: 40px;
				width: 80px;
				line-height: 40px;
				padding-left: 10px;
			}
		}
	}

	.dept,
	.user {
		overflow: hidden;
		.container {
			height: calc(100% - 40px);
		}
	}

	@media only screen and (max-width: 768px) {
		.dept {
			width: calc(100% - 100px);
		}
	}
}
</style>
